#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in.h>
#define SERVPORT 3333 //定义端口号
#define BACKLOG 10 //请求队列中允许的最大请求数
#define MAXDATASIZE 1024 //数据长度

int main() {
    struct sockaddr_in server_sockaddr, client_sockaddr;
    int sin_size, recvbytes;
    int sockfd, client_fd; 
    char buf[MAXDATASIZE];

    if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("创建 server socket 失败");
        exit(1);
    }

    printf("Socket success!,sockfd=%d\n", sockfd);

    server_sockaddr.sin_family = AF_INET;
    server_sockaddr.sin_port = htons(SERVPORT);
    server_sockaddr.sin_addr.s_addr = INADDR_ANY;
	
    if((bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr))) == -1) {
        perror("bind");
        exit(-1);
    }

    printf("bind success!\n");
	
    if(listen(sockfd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }

    printf("listening ... \n");
	
    if((client_fd = accept(sockfd,(struct sockaddr *) &client_sockaddr, &sin_size)) == -1) {
        perror("accept");
        exit(1);
    }

    printf("accept success!\n");
	
	// 调用 fcntl 将客户端连接套接字设置为非阻塞
	fcntl(client_fd, F_SETFL, O_NONBLOCK);	
	
	// 轮询 + 非阻塞 I/O 读数据	
	for (;;) {	
		recvbytes = read(client_fd, buf, MAXDATASIZE);
	
    	if(recvbytes == -1) {
			// 数据没有准备好，则继续轮询
			if (errno == EAGAIN) continue;
        	perror("recv");
        	exit(1);
    	}
		if (recvbytes == 0) {
			// 客户端断开连接
			break;
		}
    	printf("received a connection : %s\n", buf);
		memset(buf, 0x00, sizeof(buf));
	}
    close(sockfd);

}
